package com.foreverwin.jzymes.production.clamp.service.impl;

import com.foreverwin.jzymes.common.constant.Constants;
import com.foreverwin.jzymes.common.domain.CarrierBind;
import com.foreverwin.jzymes.common.domain.CarrierScanLog;
import com.foreverwin.jzymes.common.enums.CarrierScanLogEnum;
import com.foreverwin.jzymes.common.mapper.CarrierScanLogMapper;
import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.common.util.BOHandleUtil;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.production.clamp.service.IClampAdviceService;
import com.foreverwin.jzymes.production.sfc.domain.SFC;
import com.foreverwin.jzymes.production.sfc.mapper.SFCMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ClampAdviceServiceImpl implements IClampAdviceService {
    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IResourceAdviceService resourceAdviceService;
    @Autowired
    IItemGroupAdviceService itemGroupAdviceService;
    @Autowired
    ICommonService commonService;
    @Autowired
    ICarrierBindAdviceService carrierBindAdviceService;
    @Autowired
    IActivityLogAdviceService activityLogAdviceService;
    @Autowired
    ISystemRuleAdviceService systemRuleAdviceService;
    @Autowired
    CarrierScanLogMapper carrierScanLogMapper;
    @Autowired
    SFCMapper sfcMapper;

    public String OPERATION_CNC2;
    public String OPERATION_CLAMP;



    /**
     * 装夹业务处理
     *
     * @param carrierScanLog
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void clampCarrier( CarrierScanLog carrierScanLog ){
        /**加载系统规则*/
        preload( carrierScanLog.getSite() );

        /**检查字段*/
        checkFieldsForClamp( carrierScanLog );

        carrierScanLog.setCreatedDateTime( new Date());

        String checkResult = carrierScanLog.getResult();
        /*if( "1".equals( checkResult ) ){
            *//**检验信息绑定结果合格*//*
            carrierCheckOk( carrierScanLog );
        }else{
            *//**检验信息绑定结果不合格*//*
            carrierCheckFail( carrierScanLog );
        }*/
        /**修改不管装夹结果是1或2都进行装夹*/
        carrierCheckOk( carrierScanLog );

        /**保存本体扫码记录*/
        saveCarrierScanLog( carrierScanLog );
    }

    /**
     * 保存本体扫码信息
     *
     * @param carrierScanLog
     */
    public void saveCarrierScanLog( CarrierScanLog carrierScanLog ){
        /**查询机种*/
        String itemGroup = itemGroupAdviceService.findItemGroupBySite( carrierScanLog.getSite() );
        carrierScanLog.setMachineType( itemGroup );
        /**查询工序*/
        String operation = resourceAdviceService.findOperationByResource( carrierScanLog.getSite(), carrierScanLog.getResrce() );
        carrierScanLog.setOperation( operation );
        /**设置Handle*/
        carrierScanLog.setHandle(BOHandleUtil.buildCarrierScanLogHandle() );

        carrierScanLogMapper.insertCarrierScanLog( carrierScanLog );
    }

    /**
     * 加载系统规则
     *
     * @param site
     */
    public void preload( String site ){

        /**获取系统规则装夹工序*/
        OPERATION_CLAMP = systemRuleAdviceService.existSystemRule( site, Constants.SYSTEM_RULE_OPERATION_CLAMP );
        /**获取系统规则CNC2工序*/
        OPERATION_CNC2 = systemRuleAdviceService.existSystemRule( site, Constants.SYSTEM_RULE_OPERATION_CNC2 );
    }

    /**
     * 检查扫码信息字段
     *
     * @param carrierScanLog
     */
    public void checkFieldsForClamp( CarrierScanLog carrierScanLog ){
        /**检查站点*/
        siteAdviceService.existSite( carrierScanLog.getSite() );
        /**检查设备*/
        Map<String,Object> resourceMap = resourceAdviceService.existResource( carrierScanLog.getSite(), carrierScanLog.getResrce() );
        /**检查设备默认工序是否装夹工序*/
        String operation = resourceAdviceService.findOperationByResource( resourceMap );
        Assert.isTrue( OPERATION_CLAMP.equals( operation ), I18nUtil.getI18nText( "production.clamp.resourceNotClampResource", new String[]{ carrierScanLog.getResrce(), operation, OPERATION_CLAMP } ) );
        /**检查本体编号*/
        Assert.hasText( carrierScanLog.getCarrier(), I18nUtil.getI18nText( "common.carrierNotBlank" ));
        /**检查检验结果*/
        Assert.hasText( carrierScanLog.getResult(), I18nUtil.getI18nText( "production.clamp.carrierCheckResultNotBlank" ));
        /**设备扫码发送时间不能为空*/
        Assert.notNull( carrierScanLog.getSendTime(), I18nUtil.getI18nText( "production.clamp.carrierCheckSendTimeNotNull" ));
    }

    /**本体检验合格*/
    public void carrierCheckOk( CarrierScanLog carrierScanLog ){

        /**查询本体绑定信息*/
        List<CarrierBind> carrierBindList = carrierBindAdviceService.findCarrierBindOnBind( carrierScanLog.getSite(), carrierScanLog.getCarrier() );
        if( carrierBindList != null && carrierBindList.size() > 0 ){
            /*List<ActivityLog> activityLogList = activityLogAdviceService.findCarrierActivityLogOnOperation( carrierScanLog.getSite(), carrierScanLog.getCarrier(), OPERATION_CNC2, carrierBindList.get(0).getStartDateTime() );
            if( activityLogList == null || activityLogList.size() == 0 ){
                carrierScanLog.setPass( CarrierScanLogEnum.N.name() );
                return;
            }*/

            /**检查本体物料在机种中不存在，自动解绑本体*/
            if( !checkCarrierItemValid( carrierScanLog.getSite(), carrierBindList ) ){
                carrierBindAdviceService.carrierUnBind( carrierBindList, carrierScanLog.getCreatedDateTime() );
            }

            /**本体上有一个料件在二夹过站则认为本体过站*/
            if( !checkCarrierPassCNC2( carrierBindList.get( 0 ) ) ){
                /**检查本体已绑定，未通过二夹则返回不做处理*/
                carrierScanLog.setPass( CarrierScanLogEnum.N.name() );
                return;
            }else {
                /**检查本体已绑定，已通过二夹则本体解绑*/
                carrierBindAdviceService.carrierUnBind( carrierBindList, carrierScanLog.getCreatedDateTime() );
            }
        }

        carrierScanLog.setPass( CarrierScanLogEnum.Y.name() );

        /**本体绑定*/
        carrierBindAdviceService.carrierBind( carrierScanLog.getSite(), carrierScanLog.getCarrier(), carrierScanLog.getCreatedDateTime() );

        /**本体过站*/
        Map<String,String> sfcMap = commonService.sfcPassByCarrier( carrierScanLog.getSite(), carrierScanLog.getCarrier(), carrierScanLog.getResrce(), carrierScanLog.getCreatedDateTime() );

        /**更新工令已下达数量*/
        for( String itemBo : sfcMap.keySet() ){
            String sfc = sfcMap.get( itemBo );
            SFC _sfc = sfcMapper.selectSFCById( BOHandleUtil.buildSFCHandle( carrierScanLog.getSite(), sfc ) );
            _sfc.setReleasedQty( _sfc.getReleasedQty() == null ? 1L : _sfc.getReleasedQty() + 1 );
            _sfc.setUpdatedDateTime( carrierScanLog.getCreatedDateTime() );
            if( _sfc.getActStartTime() == null ){
                _sfc.setActStartTime( carrierScanLog.getCreatedDateTime() );
                _sfc.setStatusBo( "StatusBO:"+ carrierScanLog.getSite() +",403" );
            }
            sfcMapper.updateSFC( _sfc );
        }
    }

    /**
     * 检查本体物料在机种是否存在
     *
     * @param site
     * @param carrierBindList
     * @return
     */
    public boolean checkCarrierItemValid( String site, List<CarrierBind> carrierBindList ){
        String itemGroup = itemGroupAdviceService.findItemGroupBySite( site );
        List<Map<String,Object>> itemGroupMemberList = itemGroupAdviceService.findItemGroupMember( site, itemGroup );
        for( CarrierBind carrierBind : carrierBindList ){
            boolean existed = false;
            for( Map<String,Object> itemGroupMember : itemGroupMemberList ){
                if( carrierBind.getItemBo().equals( itemGroupMember.get( "ITEM_BO" ) ) ){
                    existed = true;
                    break;
                }
            }
            if( !existed ){
                return false;
            }
        }
        return true;
    }

    /**
     * 查询本体是否在二夹过站
     *
     * @param carrierBind
     * @return
     */
    public boolean checkCarrierPassCNC2( CarrierBind carrierBind ){
        return commonService.checkCarrierPassOnOperation( carrierBind, OPERATION_CNC2 );
    }

    /**本体检验不合格*/
    public void carrierCheckFail( CarrierScanLog carrierScanLog ){
        carrierScanLog.setPass( CarrierScanLogEnum.N.name() );
    }
}
